/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.groupb.circus.impl_interfaces;

import com.groupb.circus.Databases.*;
import com.groupb.circus.UserInterface.UserInterfaceLogin;
import com.groupb.circus.UserInterface.UserInterfaceP;
import com.groupb.circus.interfaces.*;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jivesoftware.smack.*;
import org.jivesoftware.smack.filter.*;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smackx.filetransfer.*;
import org.jivesoftware.smackx.muc.MultiUserChat;
import org.xmldb.api.base.XMLDBException;

/**
 *
 * @author bhavna
 */
public class InstantMessage implements com.groupb.circus.interfaces.InstantMessage {

    private static InstantMessage instantMessage = null;
    private static Log log = LogFactory.getLog(InstantMessage.class);
    private String aLogin = "";
    private PacketFilter filter = null;
    private PacketListener hi = null;
    private MultiUserChat chat = null;
    private List<String> users = null;
    private XMPPConnection con = null;
    protected Listener escucha;
    Listener listener = new com.groupb.circus.impl_interfaces.ListenerImpl(this);
    UserInterfaceP ui = null;
    FTransferListener Ftl = null;
    String path_Download=null;

    public InstantMessage(final Listener l) {
        escucha = l;
    }

    private InstantMessage() {
    }

    public synchronized static InstantMessage getInstance() {

        if (instantMessage == null) {
            instantMessage = new InstantMessage();

        }
        return instantMessage;
    }

    public void sendChat(final String receive, final String msgtransm) {
        final Message msg = new Message();
        msg.setPacketID("CHAT");
        msg.setTo(receive);
        msg.setBody(msgtransm);
        msg.setProperty("CHATMESSAGE", new Date());
        send(msg);
    }

    public void send(final Message msg) {
        try {
            chat.sendMessage(msg);
        } catch (XMPPException ex) {
            Logger.getLogger(InstantMessage.class.getName()).log(Level.SEVERE, null, ex);
            ex.printStackTrace();
        }
    }

    @Override
    public boolean login(final String aLogin, final String aPassword, String resource) {


        this.aLogin = aLogin;
        boolean flag = true;
        

        try {

            ConnectionConfiguration config = new ConnectionConfiguration("talk.google.com", 5222, "gmail.com");
            config.setSASLAuthenticationEnabled(true);
            config.setReconnectionAllowed(true);
            con = new XMPPConnection(config);
            con.connect();


            con.login(aLogin, aPassword, resource);
            filter = new AndFilter(new PacketTypeFilter(Message.class), new NotFilter(new FromContainsFilter(con.getUser())));

            con.addPacketListener((PacketListener) listener, filter);
            chat = new MultiUserChat(con, aLogin + "ChatCircus");

            
            Ftl = new FTransferListener(this);
            FileTransferManager Ftm = new FileTransferManager(con);
            FileTransferNegotiator.setServiceEnabled(con, true);
            Ftm.addFileTransferListener(Ftl);



        } catch (Throwable ex) {

            flag = false;

        }


        return flag;


        // TODO: Actualizar roster con nuevos usuarios



    }
    
    public Roster getRoster() {
        return con.getRoster();
    }

    @Override
    public void logout() {
        if (con != null) {
            con.disconnect();
        }
    }


    @Override
    public void getContent(String url, String user_url) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void addListener(final Listener listener, PacketFilter filter) {

        con.createPacketCollector(filter);
        con.addPacketListener(listener, filter);

    }

    @Override
    public void searchContent(SearchProfile search) {
    }
/*
 * Envia paquete SerachProdile
 */
    public void SendSearchProfile(String to, SearchProfile PacketSProfile) {
        final Message message = new Message();
        message.setTo(to);// Le asigno a quien va el mensaje
        message.setBody(PacketSProfile.getKeyword());
        message.setProperty("SEARCHPROFILE", PacketSProfile);//Le pongo propiedad y el mensaje searchprofile para enviar

        try {
            chat.sendMessage(message);
        } catch (XMPPException ex) {
            Logger.getLogger(InstantMessage.class.getName()).log(Level.SEVERE, null, ex);
            log.debug("Message not send to ..." + to);
        }



    }// cierra clase sendSearchProfile
    
    /*
     * Procesa el paquete SearchpRrofile que le ha llegado
     */

    public SearchResultImpl ProcessSearchProfile(String from, Message MsgProfile) throws FileNotFoundException {
        
        List<Images> list = null;
        String type = "";
        List<News> news_list = null;
        List<Content> LContents = new ArrayList<Content>();
        Content QueryContents;
        SearchResultImpl resultQuery = null;
        SearchProfile word = (searchProfile)MsgProfile.getProperty("SEARCHPROFILE");
        
        String TypeOfQuery = word.getQueryType();
        
        try {
           
            
        DAOIm querySearch = DAOIm.getInstance();
        
        /*
         * Identificamos las consultas
         */
        if(TypeOfQuery.equals("PHOTOTITLE")){
            type="photo";
            list = querySearch.TitleSearchPhoto(MsgProfile.getBody());
           }
        
        if(TypeOfQuery.equals("PHOTOKEYWORD")){
            type="photo";
            list = querySearch.KeywordSearchPhoto(MsgProfile.getBody());
           }
        
        if(TypeOfQuery.equals("PHOTOUSER")){
            type="photo";
            list = querySearch.UserSearchPhoto(MsgProfile.getBody());
           }
        
        if(TypeOfQuery.equals("PHOTOLOCALIZATION")){
            type="photo";
            list = querySearch.LocalizationSearchPhoto(MsgProfile.getBody());
           }
        
        
        if(TypeOfQuery.equals("NEWSTITLE")) {
            type="news";
            news_list = querySearch.TitleNews(MsgProfile.getBody());
        }
        
        if(TypeOfQuery.equals("NEWSTITLE")) {
            type="news";
            news_list = querySearch.TitleNews(MsgProfile.getBody());
        }
        
        if(TypeOfQuery.equals("NEWSAUTHOR")) {
            type="news";
            news_list = querySearch.NewsAuthor(MsgProfile.getBody());
        }
        
        if(TypeOfQuery.equals("NEWSPARAGRAPH")) {
            type="news";
            news_list = querySearch.ParagraphWord(MsgProfile.getBody());
        }
        
        
      
          /*
           * Metemos los resultado de la consulta en una lista de objetos Content
           */
         if(type.equals("photo")){  
          
             for ( Iterator iterador = list.listIterator(); iterador.hasNext(); ) {
                  Images b = (Images) iterador.next();
                  QueryContents = new Content("photo",b.getId(),b.getTitle(),b.getAuthor(),b.getPath(),MsgProfile.getTo());
                  LContents.add(QueryContents);
           }
          
         }    
         if(type.equals("news")){
            
             for ( Iterator iterador = news_list.listIterator(); iterador.hasNext(); ) {
                  News n = (News) iterador.next();
                  QueryContents = new Content("news",n.getId(),n.getTitle(),n.getAuthor(),MsgProfile.getTo(),n.getParagraph());
                  LContents.add(QueryContents);
           }
             
             
         }

         
           resultQuery = new SearchResultImpl(LContents);
           
           
          
           
        } //cierra la clase ProcessSearchProfile
        catch (InterruptedException ex) {
            Logger.getLogger(InstantMessage.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(InstantMessage.class.getName()).log(Level.SEVERE, null, ex);
        } catch (XMLDBException ex) {
            Logger.getLogger(InstantMessage.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            Logger.getLogger(InstantMessage.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            Logger.getLogger(InstantMessage.class.getName()).log(Level.SEVERE, null, ex);
        }
        
      return resultQuery;  
        
        
        
    }//cierra la clase ProcessSearchProfile

    public void SendSearchResult(String to, SearchResult PacketSResult) {
       
        
        final Message msg = new Message();
        
        
            /*
             * En esta clase enviaremos el paquete searchResult con los contenidos
             * encontrados en la consulta a la base de datos con paquete searchProfile
             */
            
            msg.setTo(to);
            msg.setProperty("SEARCHRESULT", PacketSResult);
            
         try{ 
            
           chat.sendMessage(msg);
        } // cierra la clase SendSearchResult
        catch (XMPPException ex) {
            Logger.getLogger(InstantMessage.class.getName()).log(Level.SEVERE, null, ex);
        }
        
    }// cierra la clase SendSearchResult
    
    
    public void SendUserContent(UserContent PacketUc,String download){
        path_Download = download;
        
        final Message messageUc = new Message();
        messageUc.setTo(PacketUc.user_id());// Le asigno a quien va el mensaje
        messageUc.setProperty("USERCONTENT", PacketUc);//Le pongo propiedad y el mensaje searchprofile para enviar

        try {
            
            chat.sendMessage(messageUc);
        } catch (XMPPException ex) {
            Logger.getLogger(InstantMessage.class.getName()).log(Level.SEVERE, null, ex);
            log.debug("Message not send to ..." + PacketUc.user_id());
        }
        
        
    }
    
    
    public void ProcessUserContent(Message msg){
       
        
        
        UserContent UserFile = (UserContent)msg.getProperty("USERCONTENT");
            
        FileTransferManager Ftm = new FileTransferManager(con);
            
        
        OutgoingFileTransfer FileTransfer = Ftm.createOutgoingFileTransfer(msg.getFrom());
        
        
        try {
  
            
            FileTransfer.sendFile(new File(UserFile.user_url()), "Download");
        } catch (XMPPException ex) {
            Logger.getLogger(InstantMessage.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    public void ProcessSearchResult(Message msg){
        
        SearchResultImpl Sresult = (SearchResultImpl)msg.getProperty("SEARCHRESULT");
        ui = UserInterfaceP.getInstance();
        
        
       
        
        if (Sresult.Content().listIterator().next().getFlag().equals("photo")) { 
            
            ui.showSearchResult(msg);
            
        }
        
        if (Sresult.Content().listIterator().next().getFlag().equals("news")){
            
            
            ui.ShowResultNew(msg);
            
        }
        
        
        
        
        
        
    }
    
    public void ProcessChat(Message msg){
        ui = UserInterfaceP.getInstance();
       
        ui.showMessageChat(msg);
    
    }
    
    
    public void ReceiveFile(FileTransferRequest ftr, String title_photo){
        
        String download = path_Download+"/"+title_photo;
        
        
        
        try {
            IncomingFileTransfer transfer = ftr.accept();
            
            transfer.recieveFile(new File(download));
            ui.ShowDownload(ftr.getFileName());
        } catch (XMPPException ex) {
            Logger.getLogger(InstantMessage.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        
    }
    
}
